#include "bsp_power.h"
#include "amLog.h"
#include "FlashLog.h"

struct PowerData_st
{
    uint8_t reset_reason;
};

static struct PowerData_st power_data;

void power_reason_update(void)
{
    if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST)  != RESET)
    {
        LOG_TS(AM_LOG_LEVEL_INFO,"POWER_REASON","Pin reset \r\n");
        power_data.reset_reason = RESET_BY_HW;
    }

    // if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST)  != RESET)
    // {
    //     LOG_TS(AM_LOG_LEVEL_INFO,"POWER_REASON","POR reset \r\n");
    // }

    if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST)  != RESET)
    {
        LOG_TS(AM_LOG_LEVEL_INFO,"POWER_REASON","SW reset \r\n");
    }

    if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET)
    {
        LOG_TS(AM_LOG_LEVEL_INFO,"POWER_REASON","IWDG reset \r\n");
        power_data.reset_reason = RESET_BY_DOG;
    }

    if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET)
    {
        LOG_TS(AM_LOG_LEVEL_INFO,"POWER_REASON","WWDG reset \r\n");
        power_data.reset_reason = RESET_BY_DOG;
    }

    if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST) != RESET)
    {
        LOG_TS(AM_LOG_LEVEL_INFO,"POWER_REASON","LP reset \r\n");
    }

    if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST)  != RESET)
    {
        LOG_TS(AM_LOG_LEVEL_INFO,"POWER_REASON","BOR reset \r\n");
    }
    SET_BIT(RCC->CSR, RCC_CSR_RMVF);

    /* print hardfault log */
    int8_t recover_ret =  log_flash_recover();
    if(0 == recover_ret)
    {
        LOG_TS(AM_LOG_LEVEL_INFO, "POWERON", "Hardfault recover\r\n");
        LogFlashData_st *flash_log = log_flash_get();
        uint16_t index = 0;
        uint8_t buf_len = 0;
        char flash_log_buf[LOG_FLASH_PRINT_MAX+1];
        while(index < flash_log->length)
        {
            buf_len = flash_log->data[index];
            if(buf_len > LOG_FLASH_PRINT_MAX)
            {
                LOG_TS(AM_LOG_LEVEL_INFO, "POWERON", "Hardfault recover overlength,exit:%d\r\n",buf_len);
                break;
            }
            memcpy(flash_log_buf,&flash_log->data[index+1],buf_len);
            flash_log_buf[buf_len] = '\0';
            LOG_TS(AM_LOG_LEVEL_INFO, "POWERON", "%s\r\n",flash_log_buf);
            index += buf_len + 1;
        }
        log_flash_clear();
        power_data.reset_reason = RESET_BY_HARDFAULT;
    }
    else
    {
        LOG_TS(AM_LOG_LEVEL_INFO, "POWERON", "no recover:%d\r\n",recover_ret);
    }
}

uint8_t get_reset_reason(void)
{
    return power_data.reset_reason;
}